package org.zoomdev.zoom.web.controller.test.modules;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zoomdev.zoom.common.caster.CasterException;
import org.zoomdev.zoom.common.exceptions.ZoomException;
import org.zoomdev.zoom.common.json.JSON;
import org.zoomdev.zoom.common.utils.MapUtils;
import org.zoomdev.zoom.ioc.annotations.IocBean;
import org.zoomdev.zoom.ioc.annotations.Module;
import org.zoomdev.zoom.ioc.annotations.ModuleInit;
import org.zoomdev.zoom.web.action.ActionContext;
import org.zoomdev.zoom.web.action.ActionInterceptor;
import org.zoomdev.zoom.web.action.ActionInterceptorAdapter;
import org.zoomdev.zoom.web.action.ActionInterceptorFactory;
import org.zoomdev.zoom.web.action.MethodActionHandler;
import org.zoomdev.zoom.web.action.PreParseInterceptor;
import org.zoomdev.zoom.web.controller.test.Monitor;
import org.zoomdev.zoom.web.exception.StatusException;
import org.zoomdev.zoom.web.parameter.PreParameterParserManager;
import org.zoomdev.zoom.web.parameter.pre.impl.FormPreParamParser;
import org.zoomdev.zoom.web.rendering.Rendering;
import org.zoomdev.zoom.web.rendering.RenderingFactory;
import org.zoomdev.zoom.web.rendering.TemplateRenderingManager;
import org.zoomdev.zoom.web.rendering.ThrowableRenderProcess;
import org.zoomdev.zoom.web.rendering.impl.JsonRendering;
import org.zoomdev.zoom.web.utils.ResponseUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Module
public class Application {


    private static final Logger log = LoggerFactory.getLogger(Application.class);

    @IocBean
    public Monitor getMonitor() {
        return new Monitor();
    }

    @ModuleInit
    public void config(ActionInterceptorFactory factory, ActionInterceptor interceptor) throws Exception {

        factory.add(interceptor, "*", 1);

        factory.add(ActionInterceptorFactory.PRE_PARSE, new PreParseInterceptor() {
            @Override
            public boolean preParse(ActionContext context) throws Exception {
                HttpServletRequest request = context.getRequest();
                String webJsonToken = request.getHeader("Authorization");
                //验证权限

                //验证通过,继续执行
                return true;
            }
        },"*",0);
    }


    public void configError(RenderingFactory factory){
//        factory.getRendering(JsonRendering.class).setThrowableRenderProcess(new ThrowableRenderProcess() {
//            @Override
//            public boolean process(ActionContext ctx, Throwable exception) {
//                //直接处理返回
//                Map<String,Object> error = MapUtils.asMap("code","xxx","message",exception.getMessage());
//                ResponseUtils.writeJson(ctx.getResponse(),error);
//                return true;
//            }
//        });

        factory.getRendering(JsonRendering.class).setThrowableRenderProcess(new ThrowableRenderProcess() {
            @Override
            public boolean process(ActionContext ctx, Throwable exception) {
                //转化异常
                if(exception instanceof CasterException){
                    ctx.setException(new StatusException.ApiError(exception.getMessage()));
                }
                //仍然由框架处理输出
                return false;
            }
        });
    }

    @ModuleInit
    public void configPreParser(PreParameterParserManager manager) {
        manager.add(context -> {
            HttpServletRequest request = context.getRequest();
            String contentType = request.getContentType();
            if (contentType != null && contentType.startsWith("myheader")) {
                return new FormPreParamParser.FormPreParameter(context.getRequest());
            }


            return null;

        });
    }


    @IocBean
    public ActionInterceptor getActionInterceptor(final Monitor monitor) throws Exception {


        return new ActionInterceptorAdapter() {

            @Override
            public boolean preParse(ActionContext context) throws Exception {
                monitor.setMethod(context.getAction().method);
                return super.preParse(context);
            }

            @Override
            public void parse(ActionContext context) throws Exception {
                super.parse(context);

            }

            @Override
            public void whenResult(ActionContext context) throws Exception {
                super.whenResult(context);
                log.info("whenResult:" + context.getAction().getKey());

                monitor.setArguments(context.getResponse(), context.getArgs());
            }

            @Override
            public boolean whenError(ActionContext context) throws Exception {
                log.error("发生异常" + context.getRequest().getServletPath(), context.getException());
                monitor.setError(context.getResponse(), context.getException());
                return super.whenError(context);
            }
        };

    }

    @ModuleInit
    public void config(TemplateRenderingManager manager) {
        manager.add("html", new TestRendering());
    }

    public static class TestRendering implements Rendering {


        @Override
        public boolean render(ActionContext context) throws Exception {
            HttpServletResponse response = context.getResponse();
            MethodActionHandler config = context.getAction();
            if (response == null) {
                throw new ZoomException("response is null");
            }

            if (response.getWriter() == null) {
                throw new ZoomException("writer is null");
            }
            response.getWriter().print(config.getKey());

            return true;
        }
    }


}
